//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#ifndef __ELASTOS_SYNCOBJECT_H__
#define __ELASTOS_SYNCOBJECT_H__

class DzTimer;
class Thread;

class SyncObject : public DLinkNode
{
    friend class Thread;
    friend class DzReaderWriterLock;
    friend class ReaderUndoOperation;

public:
    Thread *GetOwner() const
    {
        return m_pOwner;
    }
    bool_t IsOwner(Thread *pThread) const
    {
        return m_pOwner == pThread;
    }
    bool_t HasOwner() const
    {
        return NULL != m_pOwner;
    }

protected:
    SyncObject()
    {
        Initialize();
    }

    ~SyncObject();

    void Initialize()
    {
        m_pOwner = NULL;
        m_waitListHead.Initialize();
    }

    void SetOwner(Thread *pOwner);
    void ClearOwner();

    void WaiterReadyToUninterruptibleSleep();
    void WaiterReadyToUninterruptibleSleep(DzTimer *pBindingTimer);

    void WaiterReadyToSleep(WaitResult *pResult);
    void WaiterReadyToSleep(DzTimer *pBindingTimer, WaitResult *pResult);

    void WakeUpOneWaiter(register bool_t bWaiveInheritedPriority = FALSE);
    void WakeUpSomeWaiters(register bool_t bWaiveInheritedPriority = FALSE);
    void WakeUpAllWaiters(register bool_t bWaiveInheritedPriority = FALSE);

    void BeginToWakeUpSomeWaiters();

    void DetachWaiter(Thread *pWaiter);

    Thread *GetPriorityHighestWaiter();

    void InsertWaiter(Thread *pWaiter);

    void WillToInheritPriority(const Thread *pWaiter);

protected:
    Thread          *m_pOwner;
    DLinkNode       m_waitListHead;
    PreemptionLock  m_waitListLock;
};

class UndoOperation : public DLinkNode
{
public:
    UndoOperation()
    {
        m_pNext = NULL;
    }

    virtual void Undo(Thread *pThread) = 0;
};

#endif //__ELASTOS_SYNCOBJECT_H__
